﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Artemis;

namespace JAWWS
{
    class Enemy : Actor
    {  
        private Weapon weapon;
        private Ball ball;
        public float step;
        private bool israndom = true;
        private bool isTracking = false;
        private float trackRange = 5.0f;
        private MainForm main;
        private float turning;
        private int[] rotDir;

        public Enemy( int level, HandGun gun, MainForm main, float initdx, float initdz)
        {
            this.Position[0] = logic.getEnemyStartingPos()[0];
            this.Position[1] = logic.getEnemyStartingPos()[1];
            this.Position[2] = logic.getEnemyStartingPos()[2];
            this.Health = logic.getTotalHealth();
            this.weapon = gun;
            this.Alive = true;
            this.step = 0.08f;
            this.applyLevel(level);
            this.child = null;
            this.sibling = null;
            this.ball = new Ball(main);
            this.LocalTransMatrix = this.IdMatrix;
            this.setDx(initdx);
            this.setDz(initdz);
            this.main = main;
            this.turning = 0.0f;
            this.rotDir = new int[3];
        }

        public void applyLevel(int level)
        {
            // Will increase the Str, Acc and Speed of the enemy based on the level of the enemy.
            // To make it simple, will just be the base level multiplied by the level;
            Strength = logic.getBaseStr() * level;
            Accuracy = logic.getBaseAcc() * level;
            Speed = logic.getBaseSpeed() * level * 0.08f;
        }
      
        public void move(Player player)
        {
            //If the Enemy is alive and player is still alive.
            if (Alive == true && player.getAlive() == true)
            {
                //if player is not in line of sight move randomly
                float deltax = (player.getPosition()[0] - Position[0]);
                float deltaz = (player.getPosition()[2] - Position[2]);
                float len = (float)Math.Sqrt((double)(deltax * deltax + deltaz * deltaz));
                if (len > trackRange)
                {
                    if (!israndom)
                    {
                        // renormalize velocity
                        deltax = getDx();
                        deltaz = getDz();
                        len = (float)Math.Sqrt((double)(deltax * deltax + deltaz * deltaz));
                        setDx(deltax / len);
                        setDz(deltaz / len);
                        israndom = true;
                    }
                    isTracking = false;
                    getRandom();
                }
                //Move in the best posible direction towards the player
                else
                {
                    isTracking = true;
                    if (len < 1.5f)
                    {
                        //Keeps the enemy from getting inside the player's camera's range
                    }
                    else
                    {
                        //Move towards the player
                        israndom = false;
                        setDx(deltax);
                        setDz(deltaz);
                        movePosition(0, Speed);
                    }
                }
            }
            else if (Alive == false)
            {
                //Do nothing, since its dead
            }
            else
            {
                getRandom();
            }
        }
        public void getRandom()
        {
            int nextStep = rand.Next(100);
            // 93% chance to move forward
            if (nextStep < 93)
            {
                movePosition(0, Speed);
                turning = 0.0f;
            }
            // 1% chance to turn 45 degrees left
            else if (nextStep < 94)
            {
                movePosition(1, Speed);
                turning = 45.0f;
            }
            // 1% chance to turn 45 degrees right
            else if (nextStep < 95)
            {
                movePosition(2, Speed);
                turning = -45.0f;
            }
            // 1% chance to turn right
            else if (nextStep < 96)
            {
                movePosition(3, Speed);
                turning = -90.0f;
            }
            // 1% chance to turn left
            else if (nextStep < 97)
            {
                movePosition(4, Speed);
                turning = 90.0f;
            }
            // 1% chance to turn 270 degrees right
            else if (nextStep < 98)
            {
                movePosition(5, Speed);
                turning = -270.0f;
            }
            // 1% chance to turn 270 degrees left
            else if (nextStep < 99)
            {
                movePosition(6, Speed);
                turning = 270.0f;
            }
            // 1% chance to turn around
            else
            {
                movePosition(7, Speed);
                turning = -180.0f;
            }
        }
        public override void attack(Actor actor, Projectile proj)
        {
            //Does nothing
        }
        public override void attack(Actor player)
        {
            //If the player is within range, alive, and in sight, attack with weapon.
            if(player.getAlive() == true && isTracking == true && Alive == true)
            {
                //Checks if player is within range to be able to attack
                float deltax = (player.getPosition()[0] - Position[0]);
                float deltaz = (player.getPosition()[2] - Position[2]);
                float deltay = (player.getPosition()[1] - Position[1]);
                float len = (float) Math.Sqrt((double) (deltax*deltax +deltay*deltay + deltaz*deltaz)) ;
                if (len < trackRange)
                {
                    int hitRate = rand.Next(100);
                    hitRate *= this.Accuracy;
                    if (hitRate >= 50)
                    {
                        //Hit player in different places for different effects
                        int hitPlace = rand.Next(100);
                        if (hitPlace >= 0 && hitPlace <= 10)
                        {
                            //Head Shot
                            player.adjustHealth(-(weapon.getBaseDammage() * Strength +10));
                        }
                        else if (hitPlace >= 11 && hitPlace <= 35)
                        {
                            //Chest Shot 
                            player.adjustHealth(-(weapon.getBaseDammage() * Strength + 5));
                        }
                        else if (hitPlace >= 36 && hitPlace <= 75)
                        {
                            //Arms Shot - will lessen the acc. of the player.
                            player.adjustHealth(-(weapon.getBaseDammage() * Strength));
                            player.setAcc(-1);
                        }
                        else
                        {
                            //Legs Shot - will lessen the speed of the player.
                            player.adjustHealth(-(weapon.getBaseDammage() * Strength));
                            player.setSpeed(-0.1f);
                        }
                    }
                    else
                    {
                        
                    }
                }
            }
        }
        public override void draw()
        {
            if (Health > 0)
            {
                GL.glEnable(GLenum.GL_TEXTURE_2D);
                //GL.glBindTexture(GLenum.GL_TEXTURE_2D, ball.texID);
                //Console.WriteLine(main.getModel());
                MD2Obj[] model = main.getModel();
                GL.glBindTexture(GLenum.GL_TEXTURE_2D, main.TexIDs[5]);
                //Model[0].setAnimation("run1");
                model[0].setPosition(this.getPosition());
                //model[0].drawFrame(model[0].getStartFrame(1), model[0].getNextFrame(), model[0].getFrameFraction(), main.TexIDs[5]);
                model[0].drawFrame(model[0].getAnimation("run1").curFrame, model[0].getAnimation("run1").endFrame, model[0].getFrameFraction(), main.TexIDs[5]);
               //ball.draw();
               GL.glDisable(GLenum.GL_TEXTURE_2D);
            }
        }
        public void updateEnemy()
        {
            GL.glPushMatrix();
                GL.glLoadIdentity();
                GL.glTranslatef(Position[0], Position[1], Position[2]);
                GL.glRotatef(turning, 0.0f, 1.0f, 0.0f);
                GL.glGetFloatv(GLenum.GL_MODELVIEW_MATRIX, this.LocalTransMatrix);
            GL.glPopMatrix();
        }
        public void setMain(MainForm main)
        {
            this.main = main;
        }
    }
}
